<template>
  <div class="app-container">
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>系统图标管理</span>
          <el-button type="primary" size="small" @click="handleAdd">
            添加图标
          </el-button>
        </div>
      </template>

      <!-- 搜索栏 -->
      <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch">
        <el-form-item label="关键词" prop="keyword">
          <el-input
            v-model="queryParams.keyword"
            placeholder="名称/编码/描述"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="分类" prop="category">
          <el-select v-model="queryParams.category" placeholder="全部" clearable style="width: 150px">
            <el-option
              v-for="dict in categoryOptions"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 120px">
            <el-option
              v-for="dict in statusOptions"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
          <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <!-- 图标表格 -->
      <el-table
        v-loading="loading"
        :data="iconList"
        row-key="id"
        border
        :default-sort="{ prop: 'updateTime', order: 'descending' }"
        style="width: 100%; margin-bottom: 20px"
      >
        <el-table-column type="index" label="序号" width="50" align="center" />
        <el-table-column prop="name" label="名称" min-width="120" />
        <el-table-column prop="code" label="编码" min-width="120" />
        <el-table-column label="图标预览" align="center" width="100">
          <template #default="scope">
            <div class="icon-preview">
              <span v-if="scope.row.type === 'font'" class="icon-font">{{scope.row.content}}</span>
              <img v-else-if="scope.row.type === 'base64' && scope.row.content" 
                :src="scope.row.content" class="icon-image" alt="图标" />
              <img v-else-if="scope.row.type === 'image' && scope.row.url" 
                :src="scope.row.url" class="icon-image" alt="图标" />
              <span v-else>无预览</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="category" label="分类" align="center" width="100">
          <template #default="scope">
            <el-tag :type="getCategoryTagType(scope.row.category)">
              {{ getCategoryName(scope.row.category) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="type" label="类型" align="center" width="100">
          <template #default="scope">
            <el-tag :type="getTypeTagType(scope.row.type)">
              {{ getTypeName(scope.row.type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述" min-width="150" show-overflow-tooltip />
        <el-table-column prop="status" label="状态" align="center" width="100">
          <template #default="scope">
            <el-switch
              v-model="scope.row.status"
              :active-value="1"
              :inactive-value="0"
              @change="handleStatusChange(scope.row)"
            ></el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="updateTime" label="更新时间" align="center" width="160">
          <template #default="scope">
            {{ parseTime(scope.row.updateTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="180">
          <template #default="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
            >编辑</el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
            >查看</el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-delete"
              @click="handleDelete(scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <el-pagination
        :current-page.sync="queryParams.page"
        :page-sizes="[10, 20, 50, 100]"
        :page-size.sync="queryParams.size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      ></el-pagination>
    </el-card>

    <!-- 添加/编辑图标对话框 -->
    <el-dialog :title="dialog.title" :visible.sync="dialog.visible" width="650px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入图标名称" />
        </el-form-item>
        <el-form-item label="编码" prop="code">
          <el-input v-model="form.code" placeholder="请输入图标编码" :disabled="form.id !== undefined" />
        </el-form-item>
        <el-form-item label="分类" prop="category">
          <el-select v-model="form.category" placeholder="请选择分类" style="width: 100%">
            <el-option
              v-for="dict in categoryOptions"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="form.description" type="textarea" placeholder="请输入图标描述" />
        </el-form-item>
        <el-form-item label="图标类型" prop="type">
          <el-radio-group v-model="iconInputType" @change="handleIconTypeChange">
            <el-radio label="upload">上传图片</el-radio>
            <el-radio label="url">图片URL</el-radio>
            <el-radio label="font">字体图标</el-radio>
            <el-radio label="svg">SVG代码</el-radio>
          </el-radio-group>
        </el-form-item>
        
        <!-- 上传图片 -->
        <el-form-item v-if="iconInputType === 'upload'">
          <el-upload
            class="icon-uploader"
            action="#"
            :http-request="uploadIcon"
            :show-file-list="false"
            :before-upload="beforeIconUpload"
          >
            <img v-if="iconPreview" :src="iconPreview" class="icon-preview-img" />
            <i v-else class="el-icon-plus icon-uploader-icon"></i>
            <div class="el-upload__tip" slot="tip">只能上传jpg/png文件，且不超过500kb</div>
          </el-upload>
        </el-form-item>
        
        <!-- 图片URL -->
        <el-form-item v-if="iconInputType === 'url'" label="URL">
          <el-input v-model="form.url" placeholder="请输入图标URL" />
          <div class="icon-preview-container" v-if="form.url">
            <img :src="form.url" class="icon-preview-img" />
          </div>
        </el-form-item>
        
        <!-- 字体图标 -->
        <el-form-item v-if="iconInputType === 'font'" label="字符">
          <el-input v-model="form.content" placeholder="请输入字体图标字符" />
          <div class="icon-preview-container" v-if="form.content">
            <span class="icon-font-big">{{form.content}}</span>
          </div>
        </el-form-item>
        
        <!-- SVG代码 -->
        <el-form-item v-if="iconInputType === 'svg'" label="SVG代码">
          <el-input v-model="form.content" type="textarea" rows="5" placeholder="请输入SVG代码" />
          <div class="icon-preview-container" v-if="form.content && form.content.startsWith('<svg')">
            <div v-html="form.content" class="svg-preview"></div>
          </div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialog.visible = false">取 消</el-button>
        <el-button type="primary" @click="submitForm">确 定</el-button>
      </div>
    </el-dialog>
    
    <!-- 查看图标详情对话框 -->
    <el-dialog title="图标详情" :visible.sync="viewDialog.visible" width="500px" append-to-body>
      <div v-if="viewIcon" class="icon-detail">
        <div class="icon-detail-preview">
          <span v-if="viewIcon.type === 'font'" class="icon-font-large">{{viewIcon.content}}</span>
          <img v-else-if="viewIcon.type === 'base64' && viewIcon.content" 
            :src="viewIcon.content" class="icon-detail-img" alt="图标" />
          <img v-else-if="viewIcon.type === 'image' && viewIcon.url" 
            :src="viewIcon.url" class="icon-detail-img" alt="图标" />
          <div v-else-if="viewIcon.type === 'svg' && viewIcon.content" 
            v-html="viewIcon.content" class="svg-preview-large"></div>
          <span v-else>无预览</span>
        </div>
        <div class="icon-detail-info">
          <p><strong>名称：</strong>{{viewIcon.name}}</p>
          <p><strong>编码：</strong>{{viewIcon.code}}</p>
          <p><strong>类型：</strong>{{getTypeName(viewIcon.type)}}</p>
          <p><strong>分类：</strong>{{getCategoryName(viewIcon.category)}}</p>
          <p><strong>描述：</strong>{{viewIcon.description || '无'}}</p>
          <p v-if="viewIcon.url"><strong>URL：</strong>{{viewIcon.url}}</p>
          <p><strong>更新时间：</strong>{{parseTime(viewIcon.updateTime)}}</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { parseTime } from '@/utils'
import request from '@/utils/request'

export default {
  name: 'IconManagement',
  data() {
    return {
      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 图标列表
      iconList: [],
      // 总记录数
      total: 0,
      // 查询参数
      queryParams: {
        page: 1,
        size: 10,
        keyword: undefined,
        category: undefined,
        status: undefined
      },
      // 分类选项
      categoryOptions: [
        { label: '导航图标', value: 'nav' },
        { label: '选项卡图标', value: 'tab' },
        { label: 'TabBar图标', value: 'tabbar' }
      ],
      // 状态选项
      statusOptions: [
        { label: '启用', value: 1 },
        { label: '禁用', value: 0 }
      ],
      // 类型选项
      typeOptions: [
        { label: '图片', value: 'image' },
        { label: 'Base64', value: 'base64' },
        { label: 'SVG', value: 'svg' },
        { label: '字体图标', value: 'font' }
      ],
      // 对话框属性
      dialog: {
        title: '',
        visible: false
      },
      // 查看对话框
      viewDialog: {
        visible: false
      },
      // 当前查看的图标
      viewIcon: null,
      // 表单数据
      form: {
        name: undefined,
        code: undefined,
        category: 'nav',
        description: undefined,
        type: 'image',
        url: undefined,
        content: undefined
      },
      // 表单校验规则
      rules: {
        name: [
          { required: true, message: '图标名称不能为空', trigger: 'blur' }
        ],
        code: [
          { required: true, message: '图标编码不能为空', trigger: 'blur' },
          { pattern: /^[a-zA-Z0-9_]+$/, message: '图标编码只能包含字母、数字和下划线', trigger: 'blur' }
        ],
        category: [
          { required: true, message: '图标分类不能为空', trigger: 'change' }
        ]
      },
      // 图标输入类型
      iconInputType: 'upload',
      // 图标预览URL
      iconPreview: ''
    }
  },
  created() {
    this.getList()
  },
  methods: {
    // 时间格式化
    parseTime,
    
    // 获取分类名称
    getCategoryName(category) {
      const found = this.categoryOptions.find(item => item.value === category)
      return found ? found.label : category
    },
    
    // 获取类型名称
    getTypeName(type) {
      const found = this.typeOptions.find(item => item.value === type)
      return found ? found.label : type
    },
    
    // 获取分类标签类型
    getCategoryTagType(category) {
      const types = {
        'nav': 'success',
        'tab': 'warning',
        'tabbar': 'primary'
      }
      return types[category] || 'info'
    },
    
    // 获取类型标签类型
    getTypeTagType(type) {
      const types = {
        'image': 'primary',
        'base64': 'success',
        'svg': 'warning',
        'font': 'info'
      }
      return types[type] || 'info'
    },
    
    // 获取图标列表
    getList() {
      this.loading = true
      const params = {
        page: this.queryParams.page,
        size: this.queryParams.size,
        keyword: this.queryParams.keyword,
        category: this.queryParams.category,
        status: this.queryParams.status
      }
      
      request({
        url: '/system/icon/list',
        method: 'get',
        params
      }).then(res => {
        this.iconList = res.data.records || []
        this.total = res.data.total || 0
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    
    // 搜索按钮操作
    handleQuery() {
      this.queryParams.page = 1
      this.getList()
    },
    
    // 重置按钮操作
    resetQuery() {
      this.$refs.queryForm.resetFields()
      this.handleQuery()
    },
    
    // 每页数量改变
    handleSizeChange(val) {
      this.queryParams.size = val
      this.getList()
    },
    
    // 当前页改变
    handleCurrentChange(val) {
      this.queryParams.page = val
      this.getList()
    },
    
    // 添加图标
    handleAdd() {
      this.dialog.title = '添加图标'
      this.dialog.visible = true
      this.iconInputType = 'upload'
      this.iconPreview = ''
      this.form = {
        name: undefined,
        code: undefined,
        category: 'nav',
        description: undefined,
        type: 'image',
        url: undefined,
        content: undefined
      }
    },
    
    // 修改图标
    handleUpdate(row) {
      this.dialog.title = '修改图标'
      this.dialog.visible = true
      this.form = JSON.parse(JSON.stringify(row))
      
      // 设置图标输入类型
      if (row.type === 'font') {
        this.iconInputType = 'font'
      } else if (row.type === 'svg') {
        this.iconInputType = 'svg'
      } else if (row.type === 'base64') {
        this.iconInputType = 'upload'
        this.iconPreview = row.content
      } else if (row.type === 'image' && row.url) {
        this.iconInputType = 'url'
      }
    },
    
    // 查看图标详情
    handleView(row) {
      this.viewIcon = JSON.parse(JSON.stringify(row))
      this.viewDialog.visible = true
    },
    
    // 删除图标
    handleDelete(row) {
      this.$confirm(`确认删除图标"${row.name}"吗？`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        request({
          url: `/system/icon/${row.id}`,
          method: 'delete'
        }).then(() => {
          this.$message.success('删除成功')
          this.getList()
        }).catch(() => {})
      }).catch(() => {})
    },
    
    // 图标状态修改
    handleStatusChange(row) {
      const status = row.status
      this.$confirm(`确认${status === 1 ? '启用' : '停用'}图标"${row.name}"吗？`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        request({
          url: `/system/icon/status/${row.id}/${status}`,
          method: 'put'
        }).then(() => {
          this.$message.success(`${status === 1 ? '启用' : '停用'}成功`)
        }).catch(() => {
          row.status = row.status === 1 ? 0 : 1
        })
      }).catch(() => {
        row.status = row.status === 1 ? 0 : 1
      })
    },
    
    // 图标类型切换
    handleIconTypeChange(type) {
      if (type === 'upload') {
        this.form.type = 'base64'
        this.form.url = undefined
      } else if (type === 'url') {
        this.form.type = 'image'
        this.form.content = undefined
        this.iconPreview = ''
      } else if (type === 'font') {
        this.form.type = 'font'
        this.form.url = undefined
        this.iconPreview = ''
      } else if (type === 'svg') {
        this.form.type = 'svg'
        this.form.url = undefined
        this.iconPreview = ''
      }
    },
    
    // 上传前校验
    beforeIconUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isPNG = file.type === 'image/png'
      const isGIF = file.type === 'image/gif'
      const isLt500K = file.size / 1024 < 500
      
      if (!isJPG && !isPNG && !isGIF) {
        this.$message.error('上传图标只能是JPG/PNG/GIF格式!')
        return false
      }
      
      if (!isLt500K) {
        this.$message.error('上传图标大小不能超过500KB!')
        return false
      }
      
      return true
    },
    
    // 上传图标
    uploadIcon(options) {
      const file = options.file
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        this.iconPreview = reader.result
        this.form.content = reader.result
      }
    },
    
    // 提交表单
    submitForm() {
      this.$refs.form.validate(valid => {
        if (valid) {
          // 构建提交数据
          const data = {
            name: this.form.name,
            code: this.form.code,
            category: this.form.category,
            description: this.form.description,
            url: this.form.url,
            content: this.form.content
          }
          
          // 新增或修改
          if (this.form.id !== undefined) {
            // 修改
            data.id = this.form.id
            request({
              url: '/system/icon/update',
              method: 'put',
              data: data
            }).then(() => {
              this.$message.success('修改成功')
              this.dialog.visible = false
              this.getList()
            }).catch(() => {})
          } else {
            // 新增
            request({
              url: '/system/icon/add',
              method: 'post',
              data: data
            }).then(() => {
              this.$message.success('添加成功')
              this.dialog.visible = false
              this.getList()
            }).catch(() => {})
          }
        }
      })
    }
  }
}
</script>

<style scoped>
.icon-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40px;
}

.icon-image {
  max-width: 40px;
  max-height: 40px;
}

.icon-font {
  font-size: 24px;
}

.icon-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-uploader .el-upload:hover {
  border-color: #409EFF;
}

.icon-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}

.icon-preview-img {
  max-width: 100px;
  max-height: 100px;
}

.icon-preview-container {
  margin-top: 10px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-font-big {
  font-size: 48px;
}

.svg-preview {
  width: 100px;
  height: 100px;
}

.icon-detail {
  display: flex;
  align-items: flex-start;
}

.icon-detail-preview {
  margin-right: 20px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  width: 120px;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-detail-img {
  max-width: 100px;
  max-height: 100px;
}

.icon-font-large {
  font-size: 64px;
}

.svg-preview-large {
  width: 100px;
  height: 100px;
}

.icon-detail-info {
  flex: 1;
}

.icon-detail-info p {
  margin: 8px 0;
}
</style> 